#ifndef ARPACKDEF_HPP
#define ARPACKDEF_HPP
extern "C" {
  void pdsaupd_(int* comm,
                int *ido,
                char *bmat,
                int *nloc,
                char *which,
                int *nev,
                double *tol,
                double *resid,
                int *ncv,
                double *v,
                int *ldv,
                int *iparam,
                int *ipntr,
                double *workd,
                double *workl,
                int *lworkl,
                int *info);
  
  void pdseupd_(int* comm,
                int *rvec,
                char *howmny,
                int *select,
                double *d,
                double *z,
                int *ldz,
                double *sigma,
                char *bmat,
                int *n,
                char *which,
                int *nev,
                double *tol,
                double *resid,
                int *ncv,
                double *v,
                int *ldv,
                int *iparam,
                int *ipntr,
                double *workd,
                double *workl,
                int *lworkl,
                int *info);  

  void pssaupd_(int* comm,
                int *ido,
                char *bmat,
                int *nloc,
                char *which,
                int *nev,
                float *tol,
                float *resid,
                int *ncv,
                float *v,
                int *ldv,
                int *iparam,
                int *ipntr,
                float *workd,
                float *workl,
                int *lworkl,
                int *info);
  
  void psseupd_(int* comm,
                int *rvec,
                char *howmny,
                int *select,
                float *d,
                float *z,
                int *ldz,
                float *sigma,
                char *bmat,
                int *n,
                char *which,
                int *nev,
                float *tol,
                float *resid,
                int *ncv,
                float *v,
                int *ldv,
                int *iparam,
                int *ipntr,
                float *workd,
                float *workl,
                int *lworkl,
                int *info);  


  void pdnaupd_(int* comm,
                int *ido,
                char *bmat,
                int *nloc,
                char *which,
                int *nev,
                double *tol,
                double *resid,
                int *ncv,
                double *v,
                int *ldv,
                int *iparam,
                int *ipntr,
                double *workd,
                double *workl,
                int *lworkl,
                int *info);
  
  void pdneupd_(int* comm,
                int *rvec,
                char *howmny,
                int *select,
                double *dr,
                double *di,
                double *z,
                int *ldz,
                double *sigmar,
                double *sigmai,
                double *workv,
                char *bmat,
                int *n,
                char *which,
                int *nev,
                double *tol,
                double *resid,
                int *ncv,
                double *v,
                int *ldv,
                int *iparam,
                int *ipntr,
                double *workd,
                double *workl,
                int *lworkl,
                int *info);  

  void psnaupd_(int* comm,
                int *ido,
                char *bmat,
                int *nloc,
                char *which,
                int *nev,
                float *tol,
                float *resid,
                int *ncv,
                float *v,
                int *ldv,
                int *iparam,
                int *ipntr,
                float *workd,
                float *workl,
                int *lworkl,
                int *info);
  
  void psneupd_(int* comm,
                int *rvec,
                char *howmny,
                int *select,
                float *dr,
                float *di,
                float *z,
                int *ldz,
                float *sigmar,
                float *sigmai,
                float *workv,
                char *bmat,
                int *n,
                char *which,
                int *nev,
                float *tol,
                float *resid,
                int *ncv,
                float *v,
                int *ldv,
                int *iparam,
                int *ipntr,
                float *workd,
                float *workl,
                int *lworkl,
                int *info);  

}

template <class REAL>
void pxsaupd(int* comm,
             int *ido,
             char *bmat,
             int *nloc,
             char *which,
             int *nev,
             REAL *tol,
             REAL *resid,
             int *ncv,
             REAL *v,
             int *ldv,
             int *iparam,
             int *ipntr,
             REAL *workd,
             REAL *workl,
             int *lworkl,
             int *info);

template <>
void pxsaupd<double>(int* comm,
                     int *ido,
                     char *bmat,
                     int *nloc,
                     char *which,
                     int *nev,
                     double *tol,
                     double *resid,
                     int *ncv,
                     double *v,
                     int *ldv,
                     int *iparam,
                     int *ipntr,
                     double *workd,
                     double *workl,
                     int *lworkl,
                     int *info);

template <>
void pxsaupd<float>(int* comm,
                    int *ido,
                    char *bmat,
                    int *nloc,
                    char *which,
                    int *nev,
                    float *tol,
                    float *resid,
                    int *ncv,
                    float *v,
                    int *ldv,
                    int *iparam,
                    int *ipntr,
                    float *workd,
                    float *workl,
                    int *lworkl,
                    int *info);

template <class REAL>
void pxseupd(int* comm,
             int *rvec,
             char *howmny,
             int *select,
             REAL *d,
             REAL *z,
             int *ldz,
             REAL *sigma,
             char *bmat,
             int *n,
             char *which,
             int *nev,
             REAL *tol,
             REAL *resid,
             int *ncv,
             REAL *v,
             int *ldv,
             int *iparam,
             int *ipntr,
             REAL *workd,
             REAL *workl,
             int *lworkl,
             int *info);  

template <>
void pxseupd<double>(int* comm,
                     int *rvec,
                     char *howmny,
                     int *select,
                     double *d,
                     double *z,
                     int *ldz,
                     double *sigma,
                     char *bmat,
                     int *n,
                     char *which,
                     int *nev,
                     double *tol,
                     double *resid,
                     int *ncv,
                     double *v,
                     int *ldv,
                     int *iparam,
                     int *ipntr,
                     double *workd,
                     double *workl,
                     int *lworkl,
                     int *info);

template <>
void pxseupd<float>(int* comm,
                    int *rvec,
                    char *howmny,
                    int *select,
                    float *d,
                    float *z,
                    int *ldz,
                    float *sigma,
                    char *bmat,
                    int *n,
                    char *which,
                    int *nev,
                    float *tol,
                    float *resid,
                    int *ncv,
                    float *v,
                    int *ldv,
                    int *iparam,
                    int *ipntr,
                    float *workd,
                    float *workl,
                    int *lworkl,
                    int *info);

// ----- non-symmetric -----
template <class REAL>
void pxnaupd(int* comm,
             int *ido,
             char *bmat,
             int *nloc,
             char *which,
             int *nev,
             REAL *tol,
             REAL *resid,
             int *ncv,
             REAL *v,
             int *ldv,
             int *iparam,
             int *ipntr,
             REAL *workd,
             REAL *workl,
             int *lworkl,
             int *info);

template <>
void pxnaupd<double>(int* comm,
                     int *ido,
                     char *bmat,
                     int *nloc,
                     char *which,
                     int *nev,
                     double *tol,
                     double *resid,
                     int *ncv,
                     double *v,
                     int *ldv,
                     int *iparam,
                     int *ipntr,
                     double *workd,
                     double *workl,
                     int *lworkl,
                     int *info);

template <>
void pxnaupd<float>(int* comm,
                    int *ido,
                    char *bmat,
                    int *nloc,
                    char *which,
                    int *nev,
                    float *tol,
                    float *resid,
                    int *ncv,
                    float *v,
                    int *ldv,
                    int *iparam,
                    int *ipntr,
                    float *workd,
                    float *workl,
                    int *lworkl,
                    int *info);

template <class REAL>
void pxneupd(int* comm,
             int *rvec,
             char *howmny,
             int *select,
             REAL *dr,
             REAL *di,
             REAL *z,
             int *ldz,
             REAL *sigmar,
             REAL *sigmai,
             REAL *workv,
             char *bmat,
             int *n,
             char *which,
             int *nev,
             REAL *tol,
             REAL *resid,
             int *ncv,
             REAL *v,
             int *ldv,
             int *iparam,
             int *ipntr,
             REAL *workd,
             REAL *workl,
             int *lworkl,
             int *info);  

template <>
void pxneupd<double>(int* comm,
                     int *rvec,
                     char *howmny,
                     int *select,
                     double *dr,
                     double *di,
                     double *z,
                     int *ldz,
                     double *sigmar,
                     double *sigmai,
                     double *workv,
                     char *bmat,
                     int *n,
                     char *which,
                     int *nev,
                     double *tol,
                     double *resid,
                     int *ncv,
                     double *v,
                     int *ldv,
                     int *iparam,
                     int *ipntr,
                     double *workd,
                     double *workl,
                     int *lworkl,
                     int *info);

template <>
void pxneupd<float>(int* comm,
                    int *rvec,
                    char *howmny,
                    int *select,
                    float *dr,
                    float *di,
                    float *z,
                    int *ldz,
                    float *sigmar,
                    float *sigmai,
                    float *workv,
                    char *bmat,
                    int *n,
                    char *which,
                    int *nev,
                    float *tol,
                    float *resid,
                    int *ncv,
                    float *v,
                    int *ldv,
                    int *iparam,
                    int *ipntr,
                    float *workd,
                    float *workl,
                    int *lworkl,
                    int *info);

#endif
